package com.tmt.jpafieldvalueconvert.impl;

import com.tmt.helper.ReflectHelper;
import com.tmt.jpafieldvalueconvert.ConverterLoader;
import com.tmt.jpafieldvalueconvert.IJpaFieldValueConverter;
import lombok.Getter;
import lombok.Setter;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Getter
@Setter
public class DefaultConverterLoader implements ConverterLoader {

    private HashMap<Class<?>, IJpaFieldValueConverter> converterMap = new HashMap<>();

    private static DefaultConverterLoader loader = null;

    private List<String> deprecatedHostNames = new ArrayList<>();

    private DefaultConverterLoader() {
    }

    public synchronized static DefaultConverterLoader getInstance() {
        if (loader == null)
            loader = new DefaultConverterLoader();
        return loader;
    }

    @Override
    public synchronized <T extends IJpaFieldValueConverter> void addConverter(Class<T> converterClazz) {
        if (converterMap.containsKey(converterClazz))
            return;

        IJpaFieldValueConverter iConverter = null;
        try {
            try {
                Method method = converterClazz.getMethod("getInstance", null);
                if (method != null) {
                    iConverter = (IJpaFieldValueConverter) method.invoke(null, null);
                }
            } catch (Exception ex) {
                iConverter = converterClazz.newInstance();
            }
        } catch (Exception e) {
        } finally {
            //初始化iConverter的属性值。
            ReflectHelper.syncSameNameProperties(this, iConverter);
            converterMap.put(converterClazz, iConverter);
        }
    }

    @Override
    public <T extends IJpaFieldValueConverter> IJpaFieldValueConverter loadConverter(Class<T> converterClazz) {
        IJpaFieldValueConverter converter = null;
        try {
            if (!converterMap.containsKey(converterClazz)) {
                addConverter(converterClazz);
            }
            converter = converterMap.get(converterClazz);
        } catch (Exception e) {
        }
        return converter;
    }
}
